package com.yrline.pay.services;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yrline.pay.proxy.PayInvoke;
import com.yrline.pay.proxy.request.CommonRequest;
import com.yrline.pay.proxy.request.FreezeRequest;
import com.yrline.pay.proxy.request.TransferRequest;
import com.yrline.pay.proxy.request.UnFreezeRequest;
import com.yrline.pay.proxy.request.vo.TransferAccDetailRequest;
import com.yrline.pay.proxy.response.FreezeResponse;
import com.yrline.pay.proxy.response.TransferResponse;
import com.yrline.pay.proxy.response.UnFreezeResponse;
import com.yrline.pay.proxy.response.vo.TransferAccDetailResponse;
import com.yrline.pay.services.vo.InvestVo;
import com.yrline.pay.services.vo.ProjectVo;
import com.yrline.pay.web.CommonUtil;
import com.yrline.pay.web.PayUtil;

@Service
public class OperatorServices {
	@Autowired
    public  RedisTemplate<String, Object> redistTemplate;
	@Autowired
	ProjectServices projectServices;
	@Autowired
	UserServices userServices;
	
	@Autowired
	PayUtil payUtil;
	
	@Autowired
	PayInvoke payInvoke;
	
	private static String OPER_key = "OPER_INFO";
	private static String OPER_complete_key = "OPER_COMPLETE_INFO";
	private static String OPER_INVEST_key = "OPER_INVEST_INFO_";
	private static String TRANSFER_key = "TRANSFER_INFO";
	
	public void save(FreezeRequest freeze){
		redistTemplate.opsForHash().put(OPER_key, freeze.getMerBillNo(), freeze);
	}
	
	public void completeOperator(FreezeResponse response){
		FreezeRequest getpr=this.getOperRecord(response.getMerBillNo());
		getpr.setIpsTrdAmt(response.getIpsTrdAmt());
		getpr.setIpsAcctNo(response.getIpsAcctNo());
		getpr.setIpsBillNo(response.getIpsBillNo());
		getpr.setIpsDoTime(response.getIpsDoTime());
		if(response.getTrdStatus()!=1){
			return;
		}
		redistTemplate.opsForHash().put(OPER_complete_key, getpr.getMerBillNo(), getpr);
		//投标
		if(getpr.getBizType() ==1){
			userServices.freezeUserMoney(getpr.getIpsAcctNo(), 1, getpr.getIpsTrdAmt());
			projectServices.inverst(getpr.getProjectNo(), getpr.getTrdAmt());
			
			InvestVo invest = new InvestVo();
			BeanUtils.copyProperties(getpr, invest);
			redistTemplate.opsForHash().put(OPER_INVEST_key+getpr.getProjectNo(), getpr.getIpsBillNo(), invest);
		}
		
	}
	
	public List<InvestVo> inverstList(String proNo){
		return (List<InvestVo>)(List)redistTemplate.opsForHash().values(OPER_INVEST_key+proNo);
	}
	
	public boolean redPack(String userIpsAccount,Integer usrType,BigDecimal amount){
		FreezeRequest req = new FreezeRequest();
		req.setMerBillNo(CommonUtil.getMerBillNo());
		req.setMerDate(new Date());
		req.setBizType(9);
		req.setRegType(1);
		req.setFreezeMerType(1);
		req.setTrdAmt(amount);
		req.setIpsAcctNo(userIpsAccount);
		CommonRequest creq=	payUtil.getDefaultRequest(req, "trade.freeze");
		req.setWebUrl(null);
		FreezeResponse response =(FreezeResponse)this.payInvoke.invoke(creq, FreezeResponse.class);
		//成功
		if(response.getTrdStatus()==1){
			UnFreezeRequest ufreq = new UnFreezeRequest();
			ufreq.setMerBillNo(CommonUtil.getMerBillNo());
			ufreq.setMerDate(new Date());
			ufreq.setFreezeId(req.getMerBillNo());
			ufreq.setBizType(4);
			ufreq.setIpsAcctNo(userIpsAccount);
			ufreq.setTrdAmt(amount);
			CommonRequest cunreq=	payUtil.getDefaultRequest(req, "trade.unFreeze");
			UnFreezeResponse unfreeresponse =(UnFreezeResponse)this.payInvoke.invoke(cunreq, UnFreezeResponse.class);
			//这里解冻成功 
			if(unfreeresponse.getTrdStatus()==1){
				this.userServices.addUserMoney(userIpsAccount, usrType, amount, null);
				
			}
			return true;
		}
		
		return false;
	}
	
	public void loan(String projectNo){
		ProjectVo poInfo =projectServices.getProject(projectNo);
		List<InvestVo> invs = this.inverstList(projectNo);
		List<TransferAccDetailRequest> d =Lists.newArrayList();
		Map<String, TransferAccDetailRequest> m = Maps.newHashMap();
		for(FreezeRequest in:invs){
			TransferAccDetailRequest r = new TransferAccDetailRequest();
			r.setFreezeId(in.getIpsBillNo());
			r.setInIpsAcctNo(poInfo.getFinaIpsAcctNo());
			r.setInMerFee(BigDecimal.ZERO);
			r.setMerBillNo(CommonUtil.getMerBillNo());
			r.setOutIpsAcctNo(in.getIpsAcctNo());
			r.setOutMerFee(BigDecimal.ZERO);
			r.setTrdAmt(in.getTrdAmt());
			d.add(r);
			m.put(r.getMerBillNo(), r);
		}
		redistTemplate.opsForHash().putAll(TRANSFER_key, m);
		
		
		TransferRequest tr = new TransferRequest();
		tr.setBatchNo(CommonUtil.getMerBillNo());
		tr.setIsAutoRepayment(3);
		tr.setMerDate(new Date());
		tr.setProjectNo(projectNo);
		tr.setTransferAccDetail(d);
		tr.setTransferMode(2);
		tr.setTransferType(1);
		
		CommonRequest _cr =payUtil.getDefaultRequest(tr, "trade.transfer");
		TransferResponse res =(TransferResponse)payInvoke.invoke(_cr, TransferResponse.class);
		BigDecimal allLoanAmount = BigDecimal.ZERO;
		for(TransferAccDetailResponse tdrs:res.getTransferAccDetail()){
			if(tdrs.getTrdStatus() ==1){
				userServices.substringFreeMoney(tdrs.getOutIpsAcctNo(), 1, tdrs.getIpsTrdAmt());
				userServices.addUserMoney(tdrs.getInIpsAcctNo(), 2, tdrs.getIpsTrdAmt(),null);
				allLoanAmount=allLoanAmount.add(tdrs.getIpsTrdAmt());
				
				updateInvestInfo(tdrs.getMerBillNo(), projectNo);
			}
		}
		projectServices.subLoanAmount(projectNo, allLoanAmount);
		
	}
	
	private void updateInvestInfo(String transferMerBillNo,String projectNo){
		//获取转账信息
		TransferAccDetailRequest trequest=(TransferAccDetailRequest)	redistTemplate.opsForHash().get(TRANSFER_key, transferMerBillNo);
		//得到冻结信息
		String freezeIPSNo=trequest.getFreezeId();
		InvestVo investVo=(InvestVo)	redistTemplate.opsForHash().get(OPER_INVEST_key+projectNo, freezeIPSNo);
		investVo.setLoadFlag(true);
		redistTemplate.opsForHash().put(OPER_INVEST_key+projectNo, freezeIPSNo, investVo);
	}
	
	public FreezeRequest getOperRecord(String merBillNo){
		return (FreezeRequest)redistTemplate.opsForHash().get(OPER_key, merBillNo);
	}
	
}
